import turbogears   as tg
import logging
import cherrypy
import model
from datetime import date, datetime, timedelta
from model                   import Action, Tag, Project, Context, Note, Priority, Property, session
from turbogears              import controllers, expose, validate, validators, redirect, error_handler, flash, widgets, view
from sqlalchemy              import and_, or_, asc
from formencode              import validators
from subcontrollers.project  import ProjectController
from subcontrollers.action   import ActionController
from subcontrollers.tag      import TagController
from subcontrollers.context  import ContextController
from subcontrollers.sandbox  import SandboxController
from subcontrollers.note     import NoteController
from subcontrollers.property import PropertyController
from subcontrollers.review import ReviewController

log = logging.getLogger("kaizen.model")

class NotesProvider(object):

    def __init__(self):
        pass

    def update(self, *args, **kw):
        self.data = session.query(Note).select()
        self.last_update = datetime.now()

    def __repr__(self):
        return self.data

class ContextProvider(object):

    def __init__(self):
        pass

    def update(self, *args, **kw):
        self.data = session.query(Context).select()
        self.last_update = datetime.now()

    def __repr__(self):
        return self.data

class ProjectProvider(object):

    def __init__(self):
        pass

    def update(self, *args, **kw):
        self.data = session.query(Project).select(Project.c.closed==0)
        self.last_update = datetime.now()
    def __repr__(self):
        return self.data

class ClosedProjectProvider(object):

    def __init__(self):
        pass

    def update(self, *args, **kw):
        self.data = session.query(Project).select(Project.c.closed==1)
        self.last_update = datetime.now()
    def __repr__(self):
        return self.data

class NextActionProvider(object):

    def __init__(self):
        pass

    def update(self, *args, **kw):
        self.last_update = datetime.now()
        self.data = session.query(Action).select(and_(Action.c.priority==0, Action.c.closed==False))

    def __repr__(self):
        return self.data

class PropertyProvider(object):
    def __init__(self):
        pass

    def update(self, *args, **kw):
        self.last_update = datetime.now()
        calendarUrl = session.query(Property).select(Property.c.key=='calendarUrl')
        if len(calendarUrl) == 0:
          calendarUrl = Property(key='calendarUrl', value='')
          calendarUrl.flush()
        else:
          calendarUrl = calendarUrl[0]
        self.calendarUrl = calendarUrl.value
        self.data = {'calendarUrl': calendarUrl} #all properties

    def __repr__(self):
        return self.data

class HistoryProvider(object):
    def __init__(self):
        pass

    def update(self, *args, **kw):
        today = date.today()
        two_weeks = timedelta(days=-14)
        two_weeks_time = today + two_weeks

        self.last_update = datetime.now()
        notes = session.query(Note).select()
        for item in notes:
            item.type = 3
        actions = session.query(Action).select(Action.c.modified > two_weeks_time.strftime("%Y-%m-%d %H:%M:%S"),order_by=[asc(Action.c.modified)])
        for item in actions:
            item.type = 2
        projects = session.query(Project).select(Project.c.modified > two_weeks_time.strftime("%Y-%m-%d %H:%M:%S"),order_by=[asc(Project.c.modified)])
        for item in projects:
            item.type = 1
        history = projects + actions + notes
        history.sort( lambda a,b: cmp( (str(b.modified)), (str(a.modified)) ) )
        self.data = history[:15]

    def __repr__(self):
        return self.data

note_provider = NotesProvider()
context_provider = ContextProvider()
project_provider = ProjectProvider()
closed_project_provider = ClosedProjectProvider()
next_action_provider = NextActionProvider()
history_provider = HistoryProvider()
property_provider = PropertyProvider()

def reload():
  note_provider.update()
  context_provider.update()
  project_provider.update()
  closed_project_provider.update()
  next_action_provider.update()
  history_provider.update()
  property_provider.update()

def init_providers(vars):
  log.debug("--------init--------")

  priorityNext = Priority()
  priorityNext.title='next'
  priorityNext.value=0
  prioritySecond = Priority()
  prioritySecond.title='none'
  prioritySecond.value=1

  note_provider.update()
  context_provider.update()
  project_provider.update()
  closed_project_provider.update()
  next_action_provider.update()
  history_provider.update()
  property_provider.update()

  vars["contexts"] = context_provider.data
  vars["projects"] = project_provider.data
  vars["closedProjects"] = closed_project_provider.data
  vars["notes"] = note_provider.data
  vars["history"] = history_provider.data
  vars["nextActions"] = next_action_provider.data
  vars["priorities"] = [priorityNext, prioritySecond]
  vars["prop_calendarUrl"] = property_provider.calendarUrl
  vars["props"] = property_provider.data

view.variable_providers.append(init_providers)

class Root(controllers.RootController):
    log.debug("---Root---")

    project = ProjectController()
    action = ActionController()
    context = ContextController()
    tag = TagController()
    note = NoteController()
    property = PropertyController()
    review = ReviewController()

    sandbox = SandboxController()

    @expose(template="kaizen.templates.welcome", content_type='text/html; charset=utf-8')
    def index(self):
        return dict(previousPage='kaizen.templates.welcome')

    @expose(content_type='text/html; charset=utf-8')
    def forward(self, template):
        return dict(tg_template=str(template))

    def refresh(self):
        reload();





